package cn.tk.utils.desensitive;

import ch.qos.logback.classic.pattern.MessageConverter;
import ch.qos.logback.classic.spi.ILoggingEvent;
import lombok.extern.slf4j.Slf4j;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by denglw on 2019/12/18.<br/>
 * Desc: 日志信息脱敏
 */
@Slf4j
public class LogConverter extends MessageConverter {

    private final Pattern pattern = Pattern.compile("\\d{11,}");

    @Override
    public String convert(ILoggingEvent event){
        // 获取原始日志
        String log = event.getFormattedMessage();
        // 获取返回脱敏后的日志
        return this.numDeal(log);
    }

    /**
     * 脱敏大于等于11位数字的日志，脱敏中间三分之一.<br/>
     * @param msg 日志消息
     * @return 脱敏结果
     */
    private String numDeal(String msg) {
        Matcher matcher = pattern.matcher(msg);
        // 脱敏处理：查找字符串中是否有符合的子字符串
        StringBuffer sb = new StringBuffer() ;
        while(matcher.find()){
            // 查找到符合规则的手机号
            String match = matcher.group() ;
            // 脱敏中间的三分之一长度, 用*替换
            int len = match.length() / 3;
            match = match.substring(0, len) + repeatChars('*', len) + match.substring(2 * len);
            // 替换掉查找到的字符串
            matcher.appendReplacement(sb, match) ;
        }
        matcher.appendTail(sb) ;
        return sb.toString();
    }

    /**
     * 重复字符拼接成字符串.<br/>
     * @param ch 字符
     * @param repeat 重复次数
     * @return 字符串
     */
    private String repeatChars(final char ch, int repeat) {
        StringBuilder result = new StringBuilder();
        for (int i = 0; i < repeat; i++) {
            result.append(ch);
        }
        return result.toString();
    }
}
